/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package MetricsRetriever;
import DBSupport.DBApi;
import LinkRetriever.DataManager;
import DataStructures.*;
import General.FileManager;
import General.Globals;
import General.Utilities;
import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

/**
 *
 * @author Manuel
 */
public class RetrievalManager extends Thread{

    private DataManager datamgr;
    private RetrieverFactory factory;
    private Project project;
    private Retriever retriever;
    private DBApi api;

    public static int noSuccess = 0;
    public static int noFailedContext = 0;
    public static int noFailedByte = 0;
    public static int noFailedCode = 0;
    public static int noFailedArchieveLink = 0;
    public static int noFailedSVNLink = 0;
    public static int noCpp = 0;
    public static long startDate;



    public RetrievalManager(DataManager dmgr, DBApi a){
        api = a;
        datamgr = dmgr;
        startDate = Calendar.getInstance().getTimeInMillis();
    }


    public void run(){

        while(datamgr.getLinksLeft()>0){
            long timeS = System.currentTimeMillis();
            //Get the retriever according to the link
            String link = datamgr.processNextLink();
            System.out.println(this.getName() + " starts processing " + link);
            factory = RetrieverFactory.getInstance(link);
            if(factory != null)
                retriever = factory.getRetriever();
            project = new Project();
            //proceed only if everything is there (link and retriever)
            if(retriever == null || link == null){
                project.setStatus(Globals.BAD_PROJECT);
            }
            else{
                ProjectInformation context = retriever.getContextData();
                //proceed only if everything is there (contextual information)
                project.setProjectInfo(context);
                project.setStatus(Globals.BAD_PROJECT);
                project.setMatcher(retriever.getMatcher());
                if(filterInfo(context)){

                    RepositoryData repoData = retriever.getRepositoryData();

                    if(this.filterRepositoryData(repoData)){
                        project.setRepositoryData(repoData);
                        project.setStatus(Globals.TOCHECK_PROJECT);

                        HashMap metrics = retriever.getMetrics();
                        //proceed only if the metrics where taken

                        if(filterMetrics(metrics)){
                            project.setCodeMetrics(metrics);
                            project.setStatus(Globals.GOOD_PROJECT);

                            BugData bugData = retriever.getBugData();
                            RetrievalManager.noSuccess++;
                            if(this.filterBug(bugData)){
                                project.setBugData(bugData);
                            }
                        }
                    }
                }
            }
            int failed = noFailedByte + noFailedCode;
            System.out.println("Storing "+project.getProjectInfo().getUrl() + " with status "+project.getStatus());
            api.updateProject(project);
            if(project.getStatus()==50)
            Utilities.writeToFile((System.currentTimeMillis()-timeS)+",", "times", true);
            //Delete all downloaded data from disk
            FileManager.cleanUp(project.getProjectInfo().getName());
            //Clean Memory
            Utilities.cleanMemory();
        }

    }

    //TODO implement
    public boolean filterInfo(ProjectInformation info){

        //TODO CHANGE AS SYSTEM SUPPORTS OTHER RETRIEVERS, LANGUAGES ETC...
            if(info == null){
                RetrievalManager.noFailedContext++;
                return false;
            }
            boolean hasName = !(info.getName() == null || info.getName().isEmpty());
            boolean hasLanguage = retriever.hasMetricsManager();
            boolean hasArchieveLink = !(info.getArchieveLink() == null || info.getArchieveLink().getName() == null || info.getArchieveLink().getName().isEmpty());
            boolean hasRepositoryLink = retriever.hasRepositoryManager();
            
            if(hasName && hasLanguage && hasRepositoryLink && hasArchieveLink)
                return true;

            else if(!hasName || !hasLanguage)
                RetrievalManager.noFailedContext++;
            
            else if(!hasArchieveLink)
                RetrievalManager.noFailedArchieveLink++;

            else if(!hasRepositoryLink)
                RetrievalManager.noFailedSVNLink++;

            return false;
   }
   

   public boolean filterMetrics(HashMap metrics){
        //TODO add other tests
            if(metrics == null || metrics.size()<2){
                RetrievalManager.noFailedByte++;
                //test on the data
                return false;
            }
            return true;
   }

   public boolean filterRepositoryData(RepositoryData data){
        //TODO add other tests
            if(data == null || data.getNoOfClasses() <10){
                RetrievalManager.noFailedCode++;
                //test on the data 
                return false;
            }

            return true;
    }

    public boolean filterBug(BugData bugData) {
        //TODO implement
        if(bugData != null)
            return true;
        return false;
    }

    


}
